#include <Ice/Ice.h>
#include <IceUtil/Thread.h>
#include <Demo.h>
#include <time.h>

using namespace std;
using namespace Ice;
using namespace Demo;

class SessionRefreshThread:
  public IceUtil::Thread,
  public IceUtil::Monitor<IceUtil::Mutex>
{
public:

  SessionRefreshThread(const IceUtil::Time& timeout, const SessionPrx& session):
    _session(session),
    _timeout(timeout),
    _terminated(false)
  {
  }
  
  virtual void
  run()
  {
    Lock sync(*this);
    while(!_terminated)
      {
	timedWait(_timeout);
	if(!_terminated)
	  {
	    try
	      {
		_session->refresh();
	      }
	    catch(const Ice::Exception& ex)
	      {
		cout << "SessionRefreshThread: " << ex << endl;
		_terminated = true;
	      }
	  }
      }
  }
  
  void
  terminate()
  {
    Lock sync(*this);
    _terminated = true;
    notify();
  }
  
private:
  
  const SessionPrx _session;
  const IceUtil::Time _timeout;
  bool _terminated;
};

typedef IceUtil::Handle<SessionRefreshThread> SessionRefreshThreadPtr;

class Client : public Ice::Application
{
public:
  
  virtual int run(int, char*[]);
};

int
main(int argc, char* argv[])
{
  Client app;
  return app.main(argc, argv);
}

int
Client::run(int argc, char* argv[])
{
  string name;
  cout << "Please enter your name ==> ";
  cin >> name;
  if(!cin.good())
    {
      return EXIT_FAILURE;
    }
  
  Ice::ObjectPrx base = communicator()->stringToProxy("SessionFactory:default -p 10000");
  SessionFactoryPrx factory = SessionFactoryPrx::checkedCast(base);
  if(!factory)
    {
      cerr << argv[0] << ": invalid proxy" << endl;
      return EXIT_FAILURE;
    }
  
  SessionPrx session = factory->create(name);
  
  SessionRefreshThreadPtr refresh = new SessionRefreshThread(IceUtil::Time::seconds(5), session);
  refresh->start();

  sleep(2);
  HelloPrx helloProxy = session->create();
  helloProxy->sayHello();
  sleep(2);
 
  refresh->terminate();
  refresh->getThreadControl().join();
  refresh = 0;
      
  session->destroy();
  factory->shutdown();
  
  return EXIT_SUCCESS;
}
